package br.usp.ime.ingpos.services;

import java.util.Date;
import java.util.List;

import org.hibernate.criterion.Restrictions;
import org.springframework.beans.BeanUtils;

import br.com.caelum.vraptor.core.Localization;
import br.com.caelum.vraptor.ioc.Component;
import br.com.caelum.vraptor.ioc.RequestScoped;
import br.usp.ime.ingpos.modelo.Candidato;
import br.usp.ime.ingpos.modelo.Inscricao;
import br.usp.ime.ingpos.modelo.Orientador;
import br.usp.ime.ingpos.modelo.ProcessoSeletivo;
import br.usp.ime.ingpos.modelo.TipoProcessoSeletivo;
import br.usp.ime.ingpos.modelo.dao.ProcessoSeletivoDao;

@RequestScoped
@Component
public class ProcessoSeletivoService
{

    final ProcessoSeletivoDao processoSeletivoDao;
    private final EmailService emailService;
    private final Localization localization;

    public ProcessoSeletivoService(
        final ProcessoSeletivoDao processoSeletivoDao,
        final EmailService emailService,
        final Localization localization)
    {
        this.processoSeletivoDao = processoSeletivoDao;
        this.emailService = emailService;
        this.localization = localization;
    }

    public List<ProcessoSeletivo> buscarTodosProcessosSeletivos()
    {
        return processoSeletivoDao.findAll();
    }

    public List<ProcessoSeletivo> buscarProcessosSeletivosVigentes()
    {
        final List<ProcessoSeletivo> processosSeletivos = processoSeletivoDao.buscarProcessosSeletivosVigentes();
        return processosSeletivos;
    }

    public List<ProcessoSeletivo> buscarProcessosSeletivosPorData(
        final Date data )
    {
        final List<ProcessoSeletivo> processosSeletivos = processoSeletivoDao.buscarProcessosSeletivosPorData( data );

        return processosSeletivos;
    }

    public ProcessoSeletivo buscarProcessoSeletivoVigentePorTipo(
        TipoProcessoSeletivo tipo )
    {
        return processoSeletivoDao.buscarProcessoSeletivoVigentePorTipo( tipo );
    }

    public ProcessoSeletivo getProcessoSeletivo(
        Long processoSeletivoId )
    {
        List<ProcessoSeletivo> processosSeletivos = processoSeletivoDao.findByCriteria( Restrictions.eq("processoSeletivoId", processoSeletivoId ));
        if (processosSeletivos.isEmpty())
        	return null;
        return processosSeletivos.get( 0 );
    }

    public void inserirProcessoSeletivo(
        ProcessoSeletivo processoSeletivo )
    {
        if( processoSeletivo.getProcessoSeletivoId() == null ) {
            processoSeletivoDao.saveOrUpdate( processoSeletivo );
        } else {
            ProcessoSeletivo processoSeletivoPersistente = this.getProcessoSeletivo( processoSeletivo.getProcessoSeletivoId() );
            BeanUtils.copyProperties( processoSeletivo, processoSeletivoPersistente, new String[] {
                "processoSeletivoId"
            } );
            processoSeletivoDao.saveOrUpdate( processoSeletivoPersistente );
        }
    }

    public void deletarProcessoSeletivo(
        ProcessoSeletivo processoSeletivo )
    {
        final ProcessoSeletivo processoSeletivoPersistente = this.getProcessoSeletivo( processoSeletivo.getProcessoSeletivoId() );
        processoSeletivoDao.delete( processoSeletivoPersistente );
    }
    
    public void finalizaProcessoSeletivo(ProcessoSeletivo processoSeletivo){
        processoSeletivo.setProcessoFinalizado( true );
        processoSeletivoDao.saveOrUpdate( processoSeletivo );
    }
    
    public List<ProcessoSeletivo> buscaProcessosSeletivosAbertos(){
        final List<ProcessoSeletivo> processosSeletivos = processoSeletivoDao.buscarProcessosSeletivosAbertos();

        return processosSeletivos; 
    }
    
    public List<ProcessoSeletivo> buscaProcessosSeletivosFechados(){
        final List<ProcessoSeletivo> processosSeletivos = processoSeletivoDao.buscarProcessosSeletivosFechados();

        return processosSeletivos; 
    }

    public void enviarEmailProfessores(
        List<Orientador> orientadores, ProcessoSeletivo processoSeletivo )
    {
        if(!orientadores.isEmpty()){
            try {
                for( Orientador orientador : orientadores ) {
                    emailService.enviarEmail( emailService.construirEmail(
                        localization.getMessage( "email_professor_processo_escolha_orientando_assunto" ),
                        construirConteudoEmail( processoSeletivo )+localization.getMessage( "email_rodape"),
                        orientador.getEmail() ) );
                }
            } catch( EmailException e ) {
                e.printStackTrace();
                throw new IllegalStateException( "Nao conseguiu enviar email" );
            }
        }
    }

    private String construirConteudoEmail(
        ProcessoSeletivo processoSeletivo )
    {

        String conteudo = localization.getMessage( "email_professor_processo_escolha_orientando",
            processoSeletivo.getDescricao(), processoSeletivo.getDataDeAbertura(),
            processoSeletivo.getDataLimiteDeInscricao());

        return conteudo;
    }

}
